﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;

using Seven.Entity;
using Seven.EntityBasic;
using Seven.MsSql.Repositories;
using Seven.Tools.Extension;

namespace Seven.Service.Powerful
{
    public partial class HrOrganizationService
    {
        /// <summary>
        /// 根据用户ID获取该用户的组织结构管理范围集合
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns></returns>
        public IEnumerable<HrOrganization> GetRangeOrgans(int userId)
        {
            using (var unit = DbFactory.UnitOfWork)
            {
                var OrganRep = unit.HrOrganization;
                return OrganRep.GetRangeOrgans(userId);
            }
        }

        #region 提供json数据

        /// <summary>
        /// 以异步方式提供组织结构的json数据
        /// </summary>
        /// <param name="id">上级id</param>
        /// <param name="filter">是否根据管理范围过滤，默认过滤</param>
        /// <returns></returns>
        public JsonResult OrganizationJson(int id, bool filter)
        {
            IEnumerable<HrOrganization> organs; IEnumerable<KeyValuePair<int, int>> count; IEnumerable<KeyValuePair<string, int>> companyIds;
            if (filter)
            {
                return OrganizationJson(id, CurrentUserOrganRange);
            }
            else
            {
                using (var unit = DbFactory.UnitOfWork)
                {
                    var organRep = unit.HrOrganization;
                    organs = organRep.GetSons(id);
                    var Temp = organs.Select(s => s.ID);
                    count = organRep.GetSonsCount(Temp).Where(w => w.Value > 0);
                    var codeTemp = organs.Select(s => s.Code).Distinct();
                    companyIds = organRep.GetCompanyIDs(codeTemp);
                }

                return new DataResult(organs.Select(s => new
                {
                    id = s.ID,
                    text = s.FullName,
                    s.ParentID,
                    iconCls = SiteCore.GetOrganIcon(s.Type),
                    state = (count.Any(a => a.Key == s.ID) ? "closed" : "open"),
                    attributes = new
                    {
                        IsGroup = s.Type == OrganType.大集团 || s.Type == OrganType.子集团,
                        IsCompany = s.Type == OrganType.公司,
                        IsDept = s.Type == OrganType.部门,
                        s.ParentID,
                        s.Code,
                        CompanyID = s.Type == OrganType.部门 ? companyIds.First(f => s.Code == f.Key).Value : -1
                    }
                })).SerializeToJsonResult();
            }
        }

        /// <summary>
        /// 以异步方式提供组织结构的json数据
        /// </summary>
        /// <param name="id">上级id</param>
        /// <param name="range">组织结构范围</param>
        /// <returns></returns>
        public JsonResult OrganizationJson(int id, IEnumerable<HrOrganization> range)
        {
            var organs = range.Where(w => w.ParentID == id && !w.IsDeleted).TryOrderBy(o => o.SortNumber);

            return new DataResult(organs.Select(s => new
            {
                id = s.ID,
                text = s.FullName,
                s.ParentID,
                iconCls = SiteCore.GetOrganIcon(s.Type),
                state = (range.Any(a => a.ParentID == s.ID && !a.IsDeleted) ? "closed" : "open"),
                attributes = new
                {
                    IsGroup = s.Type == OrganType.大集团 || s.Type == OrganType.子集团,
                    IsCompany = s.Type == OrganType.公司,
                    IsDept = s.Type == OrganType.部门,
                    s.ParentID,
                    s.Code,
                    CompanyID = s.Type == OrganType.部门 ? range.Any(a => a.Code == s.Code.Substring(0, 2)) ? range.First(f => s.Code.Substring(0, 2) == f.Code).ID : -1 : -1
                }
            })).SerializeToJsonResult();
        }

        /// <summary>
        /// 提供公司的json数据
        /// </summary>
        /// <param name="filter">是否根据管理范围过滤</param>
        /// <returns></returns>
        public JsonResult CompanyJson(bool filter)
        {
            IEnumerable<HrOrganization> organs;
            if (filter)
            {
                organs = CurrentUserCompanyRange;
            }
            else
            {
                using (var unit = DbFactory.UnitOfWork)
                { organs = unit.HrOrganization.GetCompanys(); }
            }

            return new DataResult(organs.Select(s => new
            {
                id = s.ID,
                text = s.Name,
                s.Code,
                iconCls = SiteCore.GetOrganIcon(s.Type),
                attributes = new { IsCompany = s.Type == OrganType.公司 }
            })).SerializeToJsonResult();
        }

        /// <summary>
        /// 提供指定公司下的部门json数据
        /// </summary>
        /// <param name="companyId">指定公司ID</param>
        /// <param name="companyCode">指定公司Code</param>
        /// <param name="showSelf">是否显示自身数据</param>
        /// <param name="filter">是否根据管理范围过滤</param>
        /// <returns></returns>
        public JsonResult DeptJsonInSpecialCompanyID(int companyId, string companyCode, bool showSelf, bool filter)
        {
            IEnumerable<HrOrganization> organs;
            if (filter)
            {
                organs = CurrentUserOrganRange.Where(w => w.Code.StartsWith(companyCode));
                if (!showSelf) { organs = organs.Where(w => w.Code != companyCode); }
                organs = organs.TryOrderBy(o => o.SortNumber);
            }
            else
            {
                using (var unit = DbFactory.UnitOfWork)
                {
                    organs = unit.HrOrganization.GetChildren(companyCode, showSelf);
                }
            }

            return new DataResult(organs.Select(s => new { id = s.ID, text = s.ShortName, s.Code, s.ParentID })).SerializeToJsonResult();
        }

        /// <summary>
        /// 以异步方式提供组织结构-用户的json数据
        /// </summary>
        /// <param name="id">上级id</param>
        /// <param name="filter">是否根据管理范围过滤，默认过滤</param>
        /// <param name="includeCurrentUser">是否包含当前登录用户，默认不包含</param>
        /// <returns></returns>
        public JsonResult OrganizationUserJson(int id, bool filter, bool includeCurrentUser = false)
        {
            IList<object> result = new List<object>(); IEnumerable<HrOrganization> organs;

            using (var unit = DbFactory.UnitOfWork)
            {
                var userRep = unit.SysUser;

                if (filter)
                {
                    var range = CurrentUserOrganRange;
                    organs = range.Where(w => w.ParentID == id && !w.IsDeleted).TryOrderBy(o => o.SortNumber);
                    var IDs = organs.Select(s => s.ID);

                    var count1 = userRep.GetUsersCountByOrganIDs(IDs, OrganType.部门).Where(w => w.Value > 0);
                    foreach (var item in organs)
                    {
                        result.Add(new
                        {
                            id = item.ID,
                            text = item.FullName,
                            iconCls = SiteCore.GetOrganIcon(item.Type),
                            state = (range.Any(a => a.ParentID == item.ID && !a.IsDeleted) || count1.Any(a => a.Key == item.ID) ? "closed" : "open"),
                            attributes = new { IsOrgan = true }
                        });
                    }
                }
                else
                {
                    var organRep = unit.HrOrganization;
                    organs = organRep.GetSons(id);

                    var IDs = organs.Select(s => s.ID);
                    var count1 = organRep.GetSonsCount(IDs).Where(w => w.Value > 0);
                    var count2 = userRep.GetUsersCountByOrganIDs(IDs, OrganType.部门).Where(w => w.Value > 0);

                    foreach (var item in organs)
                    {
                        result.Add(new
                        {
                            id = item.ID,
                            text = item.FullName,
                            item.ParentID,
                            iconCls = SiteCore.GetOrganIcon(item.Type),
                            state = (count1.Any(a => a.Key == item.ID) || count2.Any(a => a.Key == item.ID) ? "closed" : "open"),
                            attributes = new
                            {
                                IsGroup = item.Type == OrganType.大集团 || item.Type == OrganType.子集团,
                                IsCompany = item.Type == OrganType.公司,
                                IsDept = item.Type == OrganType.部门,
                                item.ParentID,
                                item.Code
                            }
                        });
                    }
                }

                var temp = userRep.GetSimpleModelByDeptID(id);
                if (!includeCurrentUser) { temp = temp.Where(w => w.ID != CurrentUserBaseInfo.UserID); }
                foreach (var item in temp)
                {
                    result.Add(new
                    {
                        id = "U" + item.ID,
                        text = item.RealName,
                        iconCls = item.Sex == Sex.男 ? "icon-male" : item.Sex == Sex.女 ? "icon-female" : "icon-unknow",
                        attributes = new { IsUser = true, UserID = item.ID }
                    });
                }

                return new DataResult(result).SerializeToJsonResult();
            }
        }

        /// <summary>
        /// 以异步方式提供组织结构-角色的json数据
        /// </summary>
        /// <param name="id">上级id</param>
        /// <param name="filter">是否根据管理范围过滤</param>
        /// <param name="includeCurrentRole">是否包含当前登录用户的角色</param>
        /// <returns></returns>
        public JsonResult OrganizationRoleJson(int id, bool filter, bool includeCurrentRole = false)
        {
            IList<object> result = new List<object>(); IEnumerable<HrOrganization> organs;

            using (var unit = DbFactory.UnitOfWork)
            {
                var roleRep = unit.SysRole;

                if (filter)
                {
                    var range = CurrentUserOrganRange.Where(w => !w.IsDeleted && (w.Type == OrganType.大集团 || w.Type == OrganType.子集团 || w.Type == OrganType.公司));
                    organs = range.Where(w => w.ParentID == id).TryOrderBy(o => o.SortNumber);
                    var IDs = organs.Where(w => w.Type == OrganType.公司).Select(s => s.ID);

                    var count1 = roleRep.GetRolesCountByCompanyIDs(IDs).Where(w => w.Value > 0);
                    foreach (var item in organs)
                    {
                        result.Add(new
                        {
                            id = item.ID,
                            text = item.FullName,
                            iconCls = SiteCore.GetOrganIcon(item.Type),
                            state = (range.Any(a => a.ParentID == item.ID) || count1.Any(a => a.Key == item.ID) ? "closed" : "open"),
                            attributes = new
                            {
                                IsGroup = item.Type == OrganType.大集团 || item.Type == OrganType.子集团,
                                IsCompany = item.Type == OrganType.公司
                            }
                        });
                    }
                }
                else
                {
                    var organRep = unit.HrOrganization;
                    organs = organRep.GetSons(id);

                    var IDs = organs.Where(w => w.Type == OrganType.公司).Select(s => s.ID);
                    var count1 = organRep.GetSonsCount(IDs).Where(w => w.Value > 0);
                    var count2 = roleRep.GetRolesCountByCompanyIDs(IDs).Where(w => w.Value > 0);

                    foreach (var item in organs)
                    {
                        result.Add(new
                        {
                            id = item.ID,
                            text = item.FullName,
                            item.ParentID,
                            iconCls = SiteCore.GetOrganIcon(item.Type),
                            state = (count1.Any(a => a.Key == item.ID) || count2.Any(a => a.Key == item.ID) ? "closed" : "open"),
                            attributes = new
                            {
                                IsGroup = item.Type == OrganType.大集团 || item.Type == OrganType.子集团,
                                IsCompany = item.Type == OrganType.公司
                            }
                        });
                    }
                }

                var temp = roleRep.GetSimpleModelByCompanyID(id, true);
                if (!includeCurrentRole) { temp = temp.Where(w => w.ID != CurrentUserBaseInfo.RoleID); }
                foreach (var item in temp)
                {
                    result.Add(new
                    {
                        id = "R" + item.ID,
                        text = item.IsDisabled ? item.Name + "（已禁用）" : item.Name,
                        iconCls = item.Icon,
                        attributes = new { IsRole = true, RoleID = item.ID }
                    });
                }

                return new DataResult(result).SerializeToJsonResult();
            }
        }

        #endregion
    }
}
